package com.nowcoder.topic.hash.middle;

import java.util.ArrayList;
import java.util.HashMap;

/**
 * NC388 砖墙的垂线
 * @author d3y1
 */
public class NC388 {
    /**
     * 代码中的类名、方法名、参数名已经指定，请勿修改，直接返回方法规定的值即可
     *
     * 画砖墙图 -> 一目了然
     *
     * "如果你画的线只是从砖块边缘经过则不算是经过。" -> 尽量从边缘经过, 垂线才能最少经过砖块!
     *
     * @param wall int整型二维数组
     * @return int整型
     */
    public int brickwall (ArrayList<ArrayList<Integer>> wall) {
        // return solution1(wall);
        return solution2(wall);
    }

    /**
     * 哈希: cnt[]
     * @param wall
     * @return
     */
    private int solution1(ArrayList<ArrayList<Integer>> wall){
        // 砖墙行数
        int n = wall.size();
        // 砖墙最右边缘
        int rightmost = 0;
        for(int width: wall.get(0)){
            rightmost += width;
        }

        // 边缘统计
        int[] cnt = new int[rightmost];
        // 每行砖块
        ArrayList<Integer> bricks;
        // 砖块边缘
        int edge;
        // 相同砖块边缘统计 取最大值
        int max = 0;
        for(int i=0; i<n; i++){
            bricks = wall.get(i);
            edge = 0;
            for(int width: bricks){
                edge += width;
                if(edge < rightmost){
                    cnt[edge]++;
                    max = Math.max(max, cnt[edge]);
                }
            }
        }

        // 砖墙行数-最大值
        return n-max;
    }

    /**
     * 哈希: cntMap
     * @param wall
     * @return
     */
    private int solution2(ArrayList<ArrayList<Integer>> wall){
        // 砖墙行数
        int n = wall.size();
        // 边缘统计
        HashMap<Integer,Integer> cntMap = new HashMap<>();
        // 每行砖块
        ArrayList<Integer> bricks;
        // 砖块边缘
        int edge;
        // 相同砖块边缘统计 取最大值
        int max = 0;
        for(int i=0; i<n; i++){
            bricks = wall.get(i);
            edge = 0;
            // 减1 排除砖墙最右边缘rightmost
            for(int j=0; j<bricks.size()-1; j++){
                // 当前砖块边缘(右)+砖块宽度
                edge += bricks.get(j);
                cntMap.put(edge, cntMap.getOrDefault(edge,0)+1);
                max = Math.max(max, cntMap.get(edge));
            }
        }

        // 砖墙行数-最大值
        return n-max;
    }
}